﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Sinacor.Infra.UI.Settings;
using PSE.Framework.Configuration;
using PSE.Framework.ProviderLoader.Configuration;
using PSE.Framework.ProviderLoader;
using PSE.Framework.UI.Settings;

namespace Sinacor.Infra.UI.Favorites
{
    public class FavoritesManager
    {
        private IConfigurationSettings<SinacorConfigurationObjectType> _settings;
        private static FavoritesManager _manager;
        private static object _locker = new object();
        private const string CONFIG_SECTION_NAME = "clientProviders";

        public FavoritesManager()
        {
            ProviderConfigurationSection configSection = ApplicationConfiguration.GetCurrent().GetSection<ProviderConfigurationSection>(CONFIG_SECTION_NAME);

            _settings = ProviderLoader<IConfigurationSettings<SinacorConfigurationObjectType>>.LoadProvider(configSection.Providers, "localSettingsProvider");
        }

        public static FavoritesManager GetInstance()
        {
            lock (_locker)
            {
                if (_manager == null)
                    _manager = new FavoritesManager();
            }

            return _manager;
        }

        public List<CompanyFavorite> GetCompanyFavorites(int companyId)
        {
            FavoriteSettings favorites = LoadLayout();

            return (from n in favorites.FavoriteCollection
                    where n is CompanyFavorite
                    where ((CompanyFavorite)n).CompanyId == companyId
                    select (CompanyFavorite)n).ToList();
        }

        public List<Favorite> GetAllCompaniesFavorites()
        {
            FavoriteSettings favorites = LoadLayout();

            return (from n in favorites.FavoriteCollection
                    where n is Favorite
                    where !(n is CompanyFavorite)
                    select n).ToList();
        }

        public bool AddFavorite(Favorite favorite)
        {
            bool sucess = false;

            FavoriteSettings favorites = LoadLayout();

            List<Favorite> f = (from n in favorites.FavoriteCollection
                                where n is Favorite
                                where !(n is CompanyFavorite)
                                where n.Assembly == favorite.Assembly
                                where n.ClassName == favorite.ClassName
                                select n).ToList();

            if (GetAllCompaniesFavorites().Count < GetFavoriteMaxNumber() && f.Count == 0)
            {
                favorites.FavoriteCollection.Add(favorite);

                SaveLayout(favorites);

                sucess = true;
            }

            return sucess;
        }

        public bool AddFavorite(CompanyFavorite companyFavorite)
        {
            bool sucess = false;

            FavoriteSettings favorites = LoadLayout();

            List<CompanyFavorite> f = (from n in favorites.FavoriteCollection
                                       where n is CompanyFavorite
                                       where n.Assembly == companyFavorite.Assembly
                                       where n.ClassName == companyFavorite.ClassName
                                       where ((CompanyFavorite)n).CompanyId == companyFavorite.CompanyId
                                       select (CompanyFavorite)n).ToList();

            if (GetCompanyFavorites(companyFavorite.CompanyId).Count < GetCompanyFavoriteMaxNumber() && f.Count == 0)
            {
                favorites.FavoriteCollection.Add(companyFavorite);

                SaveLayout(favorites);

                sucess = true;
            }

            return sucess;
        }

        public bool RemoveFavorite(string assembly, string className)
        {
            bool sucess = false;

            FavoriteSettings favorites = LoadLayout();

            if (favorites.FavoriteCollection.Contains(assembly + className))
            {
                favorites.FavoriteCollection.Remove(assembly + className);

                SaveLayout(favorites);

                sucess = true;
            }

            return sucess;
        }

        public bool RemoveFavorite(int companyId, string assembly, string className)
        {
            bool sucess = false;

            FavoriteSettings favorites = LoadLayout();

            if (favorites.FavoriteCollection.Contains(companyId.ToString() + assembly + className))
            {
                favorites.FavoriteCollection.Remove(companyId.ToString() + assembly + className);

                SaveLayout(favorites);

                sucess = true;
            }

            return sucess;
        }

        private void SaveLayout(FavoriteSettings favorites)
        {
            _settings.BeginSaveOrLoadOperation(favorites);

            _settings.Save(favorites);

            _settings.EndSaveOrLoadOperation();
        }

        private FavoriteSettings LoadLayout()
        {
            IConfigurationObject<SinacorConfigurationObjectType> favorites = new FavoriteSettings();

            favorites.ConfigurationType = SinacorConfigurationObjectType.Favorites;

            favorites.ConfigurationName = "FavoriteCollection";

            ((FavoriteSettings)favorites).FavoriteCollection = new FavoriteCollection();

            _settings.BeginSaveOrLoadOperation(favorites);

            _settings.Load(ref favorites);

            _settings.EndSaveOrLoadOperation();

            return (FavoriteSettings)favorites;
        }

        private int GetFavoriteMaxNumber()
        {
            return Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["FavoriteMaxNumber"]);
        }

        private int GetCompanyFavoriteMaxNumber()
        {
            return Convert.ToInt32(System.Configuration.ConfigurationManager.AppSettings["CompanyFavoriteMaxNumber"]);
        }
    }
}
